package main

import "fmt"

/**
 slice与array接近，但是呢数组array是不能增加元素的，slice可以增加元素
并且实现长度自增。
并且，slice总是指向底层的一个array，而array是一个指向array的指针
slice是引用类型，这意味着当赋值某个slice到另一个变量，两一个变量会同时指向同一个array
*/

/**
slice可通过append来扩展slice s的元素，并返回新的、与s有相同类型的slice。如果s没有
足够的容量来存储追加的值，append分配一个足够大的、新的slice来存放原有的slice的元素和
追加的值，也因为这个append返回的slice可能是指向不同底层的array
*/

/**
函数copy从源slice src赋值元素的目标dst，并且返回复制的元素的个数。源与目标可鞥重叠，。
元素赋值的数量是len(src)和len(dst)中的最小值
*/
func main() {
	a := [...]int{1, 2, 3, 4, 5} //定义长度为5的数组
	s1 := a[2:4]                 //创建从索引2到索引4-1的slice，包含的array的元素有3，4
	s2 := a[1:5]                 //创建从索引1到索引5-1的slice，包含的array的元素有2，3，4，5
	s3 := a[:]                   //创建从array开始到中止slice，包含的array的元素有1，2，3，4，5
	//上方的写法实际上是a[0:len(a)]的简化写法
	s4 := a[:4] //创建从索引0到索引4-1的slice，包含的array的元素有1，2，3，4
	//上方的写法实际上是a[0:4]的简化写法
	s5 := s2[:] //从slice s2创建slice，但s5仍然指向array a
	fmt.Println(s1, "\t", s2, "\t", s3, "\t", s4, "\t", s5)

	s6 := []int{0, 0}         //创建两个元素的array
	s7 := append(s6, 2)       //向这个array添加2这个元素，并返回添加后的slice，等价于s2 := [...]int{0,0,2}
	s8 := append(s7, 3, 5, 7) //向这个array添加3,5,7这个元素，并返回添加后的slice，等价于s2 := [...]int{0,0,2,3,5,7}
	s9 := append(s8, s6...)   //向这个array添加s6所有的元素，并返回添加后的slice，等价于s2 := [...]int{0,0,2,3,5,7,0,0}
	//注意，要是添加的元素是个slice或array的话，需要在其后面添加三个点...
	fmt.Println(s6, "\t", s7, "\t", s8, "\t", s9, s6)

	s10 := [...]int{1, 2, 3, 4, 5, 6} //创建array数组
	s11 := make([]int, len(s10))      //创建与s10一样长度的slice但是值都为0
	s12 := copy(s11, s10[0:])         //将s10从索引0到终止位置的所有的元素都复制到s11中，并返回复制元素的长度
	//等价于s11 = s10[0:]，返回len(s10[0:])
	s13 := copy(s11, s10[2:]) //将s10从索引2到终止位置的所有的元素都复制到s11中，并返回复制元素的长度
	//等价于s11 = s10[2:]，返回len(s10[2:])
	fmt.Println(s10, "\t", s11, "\t", s12, "\t", s13)
}
